#!/bin/bash
source "./emsdk/emsdk_env.sh" > /dev/null 2>&1

# 编译参数
SOURCE_FILES=(

    "cpp/log.cpp" 

    # 数学
    "cpp/math/vec3.cpp" 
    "cpp/math/quat.cpp" 


    #几何
    "cpp/geometry/aabb.cpp" 
    "cpp/geometry/intersect3d.cpp" 


    # 节点
    "cpp/scene/node.cpp"


    # 渲染组件
    "cpp/renderer/model.cpp"

    # 组件
    ## 物理组件
    "cpp/physics/collider-base.cpp"
    "cpp/physics/collider-box.cpp"
    "cpp/physics/collider-sphere.cpp"
    "cpp/physics/physics.cpp"

    # 入口
    "cpp/engine.cpp"
     "cpp/glue.cpp"
)

OUTPUT_DIR="dist"  # 自定义输出目录名
mkdir -p "$OUTPUT_DIR"  # 自动创建目录

EMSCRIPTEN_FLAGS=(
    -I.
    -std=c++17
    --bind                  # Embind 必须前置
    -flto                  # 链接时优化（关键性能提升）
    -O3                    # 最高优化级别    参照下边的编译优化：编译优化
    
    # WASM 核心配置
    -s WASM=1
    -s MODULARIZE=1
    -s ENVIRONMENT='web,worker'
    -s SINGLE_FILE=1        # Base64 内联 WASM
    
    # 内存和指针配置
    -s ALLOW_MEMORY_GROWTH=1
    -s WASM_BIGINT=1        # 确保 64 位指针支持
    -s ASSERTIONS=0         # 禁用断言（发布模式）
    -s DISABLE_EXCEPTION_CATCHING=1  # 禁用异常捕获（减体积）
    
    # 导出配置
    -s EXPORTED_RUNTIME_METHODS=['HEAPF32','ccall','cwrap','UTF8ToString']
    -s EXPORT_NAME="Carlos"
    -o "${OUTPUT_DIR}/carlos.js"
)



# 执行编译
echo "正在编译为 WASM..."
em++ "${SOURCE_FILES[@]}" "${EMSCRIPTEN_FLAGS[@]}"


# 检查结果
if [ $? -eq 0 ]; then
    echo "编译成功！生成文件："
    # ls -lh $OUTPUT_NAME.*
else
    echo "编译失败！"
    exit 1
fi


# 编译优化
# -O0	无优化	禁用所有优化，保留调试信息，代码完全按原始逻辑执行。	调试阶段
# -O1	基础优化	减少代码体积和执行时间，不影响调试。	开发中快速测试
# -O2	中级优化	包括指令调度、循环优化等，几乎不增加编译时间。	发布版本（平衡性能与编译速度）
# -O3	高级优化	激进的优化（如循环展开、向量化），可能增加代码体积。	计算密集型代码
# -Os	体积优化	在 -O2 基础上优先减少代码体积。	嵌入式或内存敏感场景
# -Ofast	超优化	启用 -O3 + 违反严格标准的行为（如快速数学计算）。	对精度不敏感的高性能计算
# -Og	调试优化	在 -O1 基础上保留更多调试信息。	需要调试的优化代码


# 减小文件体积
# em++ vec3.cpp glue.cpp \
#     -Os \  # 优化大小
#     -s STRICT=1 \
#     -s DISABLE_EXCEPTION_CATCHING=1 \
#     -o vec3.js
# 生成 TypeScript 定义
# embind-gen vec3.h --typescript > vec3.d.ts
# 直接内存访问
# 如果 JS 需要频繁读写 vec3 的数据，可以通过内存指针操作：
# cpp
# // 在 glue.cpp 中添加
# EMSCRIPTEN_BINDINGS(memory) {
#     function("getVec3Ptr", &vec3::getPtr, allow_raw_pointers());
# }